package com.itheima.elasticsearch;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.itheima.elasticsearch.pojo.Article;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.IndicesAdminClient;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.Test;

import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;

public class Demo02 {
    //创建索引库
    @Test
    public void test01() throws Exception {
        //创建ES传输客户端对象
        TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY);
        //添加传输地址对象
        transportClient.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"),9300));
        //创建索引库
        transportClient.admin().indices().prepareCreate("blog2").get();
        //释放资源
        transportClient.close();
    }

    //删除索引库
    @Test
    public void test02() throws Exception {
        //创建ES传输客户端地址
        TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY);
        //添加传输地址对象
        transportClient.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"),9300));
        //删除索引库
        transportClient.admin().indices().prepareDelete("blog2").get();
        //释放资源
        transportClient.close();
    }

    //创建索引库表映射
    @Test
    public void test03() throws Exception {
        //1.创建ES传输客户端地址
        TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY);
        //1.1添加传输地址对象
        transportClient.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"),9300));
        // 2. 创建索引库管理客户端
        IndicesAdminClient indices = transportClient.admin().indices();
        // 2.1 创建空的索引库
        indices.prepareCreate("blog2").get();
        // 3. 创建内容构建对象
        XContentBuilder builder = XContentFactory.jsonBuilder();
        builder.startObject().startObject("article").startObject("properties");
        builder.startObject("id").field("type","long").field("store",true).endObject();
        builder.startObject("title").field("type","text").field("store",true).field("analyzer","ik_smart").endObject();
        builder.startObject("content").field("type","text").field("store",true).field("analyzer","ik_smart").endObject();
        builder.endObject();
        builder.endObject();
        builder.endObject();
        // 4. 创建映射请求对象
        PutMappingRequest mappingRequest = new PutMappingRequest("blog2").type("article").source(builder);
        // 5. 为索引库类型添加映射
        indices.putMapping(mappingRequest).get();
        //6. 释放资源
        transportClient.close();
    }

    //创建文档(使用Map)
    @Test
    public void test04() throws Exception {
        //创建ES传输客户端对象
        TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY);
        //添加传输地址对象
        transportClient.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"),9300));
        //创建map集合封装文档
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("id",1);
        map.put("title","elasticsearch搜索服务");
        map.put("content","ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎。");
        //添加文档
        transportClient.prepareIndex("blog2","article","1").setSource(map).get();
        //释放资源
        transportClient.close();
    }

    //创建文档(使用Jackson)
    @Test
    public void test05() throws Exception {
        //创建ES传输客户端对象
        TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY);
        //添加传输对象地址
        transportClient.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"),9300));
        //创建实体类
        Article article = new Article();
        article.setId(2);
        article.setTitle("dubbo分布式服务框架");
        article.setContent("dubbo阿里巴巴开源的高性能的RPC框架");

        //把article转化成json字符串
        String jsonStr = new ObjectMapper().writeValueAsString(article);
        //添加文档
        transportClient.prepareIndex("blog2","article","2").setSource(jsonStr, XContentType.JSON).get();
        //释放资源
        transportClient.close();
    }

   //修改文档
    @Test
    public void test06() throws Exception {
        //创建ES传输客户端对象
        TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY);
        //添加传输地址对象
        transportClient.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"),9300));
        //创建对象
        Article article = new Article();
        article.setId(2);
        article.setTitle("dubbo分布式服务框架2");
        article.setContent("dubbo阿里巴巴开源的高性能的RPC框架2");
        //把article转化成json字符串
        String jsonStr = new ObjectMapper().writeValueAsString(article);
        //修改文档
        transportClient.prepareUpdate("blog2","article","2").setDoc(jsonStr,XContentType.JSON).get();
        //释放资源
        transportClient.close();
    }

    //删除文档
    @Test
    public void test07() throws Exception {
        //创建ES传输客户端对象
        TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY);
        //添加传输地址对象
        transportClient.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"),9300));
        //删除文档
        transportClient.prepareDelete("blog2","article","2").get();
        //释放资源
        transportClient.close();
    }

    //批量添加文档
    @Test
    public void test08() throws Exception {
        //创建ES传输客户端对象
        TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY);
        //添加传输地址对象
        transportClient.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"),9300));
        //创建批量请求构建对象
        BulkRequestBuilder bulkRequestBuilder = transportClient.prepareBulk();
        long begin = System.currentTimeMillis();
        //循环创建文档，添加索引请求对象
        for (long i = 1; i <= 1000; i++) {
            Article article = new Article();
            article.setId(i);
            article.setTitle("dubbo分布式服务框架" + i);
            article.setContent("dubbo阿里巴巴开源的高性能的RPC框架" + i);
            //创建索引请求对象
            IndexRequest indexRequest = new IndexRequest("blog2","article",i + "")
                    .source(new ObjectMapper().writeValueAsString(article),XContentType.JSON);
            //添加索引请求对象
            bulkRequestBuilder.add(indexRequest);
        }
        //提交请求
        bulkRequestBuilder.get();
        long end = System.currentTimeMillis();
        System.out.println("秒数：" + (end - begin)/1000);
        //释放资源
        transportClient.close();
    }

    //搜索分页与排序
    @Test
    public void test09() throws Exception {
        //创建ES传输客户端对象
        TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY);
        //添加传输地址对象
        transportClient.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"),9300));
        //创建搜索请求构建对象
        SearchRequestBuilder searchRequestBuilder = transportClient.prepareSearch("blog2").setTypes("article");
        //设置查询条件
        searchRequestBuilder.setQuery(QueryBuilders.matchAllQuery());
        //设置分页起始数 (当前页码 - 1) * 页大小
        searchRequestBuilder.setFrom(0);
        //设置页大小
        searchRequestBuilder.setSize(5);
        //设置根据id排序(升序)
        searchRequestBuilder.addSort("id", SortOrder.ASC);
        //执行请求，得到搜索响应对象
        SearchResponse searchResponse = searchRequestBuilder.get();
        //获取搜索结果
        SearchHits hits = searchResponse.getHits();
        System.out.println("总命中数：" + hits.totalHits);
        //迭代搜索结果
        for (SearchHit hit : hits) {
            System.out.println("JSON字符串：" + hit.getSourceAsString());
        }
        //释放资源
        transportClient.close();
    }

    //高亮显示
    @Test
    public void test10() throws Exception {
        //创建ES传输客户端对象
        TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY);
        //创建传输地址对象
        transportClient.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"),9300));
        //创建搜索请求构建对象
        SearchRequestBuilder searchRequestBuilder = transportClient.prepareSearch("blog2").setTypes("article");
        //设置查询条件
        searchRequestBuilder.setQuery(QueryBuilders.termQuery("content","开源"));
        //创建高亮构建对象
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        //设置高亮字段
        highlightBuilder.field("content");
        //设置高亮格式器前缀
        highlightBuilder.preTags("<font color='red'>");
        //设置高亮格式器后缀
        highlightBuilder.postTags("</font>");
        //设置高亮对象
        searchRequestBuilder.highlighter(highlightBuilder);
        //执行请求，得到搜索响应对象
        SearchResponse searchResponse = searchRequestBuilder.get();
        //获取搜索结果
        SearchHits hits = searchResponse.getHits();
        System.out.println("总命中数：" + hits.totalHits);
        //迭代搜索结果
        for (SearchHit hit : hits) {
            //获取高亮字段集合
            Map<String,HighlightField> highMap = hit.getHighlightFields();
            //获取content字段的高亮内容
            String content = highMap.get("content").getFragments()[0].toString();
            System.out.println(hit.getSourceAsMap().get("id") + "\t" + hit.getSourceAsMap().get("title") + "\t" + content);
        }
        //释放资源
        transportClient.close();
    }
}
